package com.tian.common.utils;

import java.util.Collection;
import java.util.Map;
import java.util.Random;

public class StringUtils extends org.apache.commons.lang3.StringUtils {

    /**
     * 获取参数不为空值
     *
     * @param value defaultValue 要判断的value
     * @return value 返回值
     */
    public static <T> T nvl(T value, T defaultValue)
    {
        return value != null ? value : defaultValue;
    }
    /**
     * 截取字符串
     *
     * @param str   字符串
     * @param start 开始
     * @param end   结束
     * @return 结果
     */
    public static String subString(final String str, int start, int end) {
        if (str == null) {
            return "";
        }

        if (end < 0) {
            end = str.length() + end;
        }
        if (start < 0) {
            start = str.length() + start;
        }

        if (end > str.length()) {
            end = str.length();
        }

        if (start > end) {
            return "";
        }

        if (start < 0) {
            start = 0;
        }
        if (end < 0) {
            end = 0;
        }

        return str.substring(start, end);
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str,String split)
    {
        if (str == null)
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++)
        {
            char c = str.charAt(i);
            if (i > 0)
            {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            }
            else
            {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1))
            {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
            {
                sb.append(split);
            }
            else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
            {
                sb.append(split);
            }
            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }
    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。 例如：HELLO_WORLD->HelloWorld
     *
     * @param name      转换前的下划线大写方式命名的字符串
     * @param split     分割字符
     * @param isUpStart 开头是否大写
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name, String split, Boolean isUpStart) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty()) {
            // 没必要转换
            return "";
        } else if (!name.contains(split)) {
            // 不含下划线，仅将首字母大写
            if (isUpStart) {
                return name.substring(0, 1).toUpperCase() + name.substring(1);
            } else {
                return name;
            }

        }
        // 用下划线将原始字符串分割
        String[] camels = name.split(split);
        if (isUpStart) {
            for (String camel : camels) {
                // 跳过原始字符串中开头、结尾的下换线或双重下划线
                if (camel.isEmpty()) {
                    continue;
                }
                // 首字母大写
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        } else {
            for (int i = 0; i < camels.length; i++) {
                // 跳过原始字符串中开头、结尾的下换线或双重下划线
                if (camels[i].isEmpty()) {
                    continue;
                }
                if (result.toString().isEmpty()) {
                    // 首字母小写
                    result.append(camels[i].substring(0, 1).toLowerCase());
                    result.append(camels[i].substring(1).toLowerCase());
                } else {
                    // 首字母大写
                    result.append(camels[i].substring(0, 1).toUpperCase());
                    result.append(camels[i].substring(1).toLowerCase());
                }

            }
        }

        return result.toString();
    }

    /**
     * 获取随机数（数字、字母）
     *
     * @param length 长度
     * @return 随机数
     */
    public static String getRandom(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            // 输出字母还是数字
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            // 字符串
            if ("char".equalsIgnoreCase(charOrNum)) {
                // 取得大写字母还是小写字母
                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) { // 数字
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val.toLowerCase();
    }

    /**
     * 获取N位随机正整数
     *
     * @param length 长度
     * @return 随机数
     */
    public static String getRandomInt(int length) {
        Random random = new Random();
        return String.valueOf(random.nextInt((int) Math.round(Math.pow(10, length))) + 1);
    }


    /**
     * * 判断一个Collection是否为空， 包含List，Set，Queue
     *
     * @param coll 要判断的Collection
     * @return true：为空 false：非空
     */
    public static boolean isEmpty(Collection<?> coll) {
        return isNull(coll) || coll.isEmpty();
    }

    /**
     * * 判断一个Collection是否非空，包含List，Set，Queue
     *
     * @param coll 要判断的Collection
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Collection<?> coll) {
        return !isEmpty(coll);
    }

    /**
     * * 判断一个对象数组是否为空
     *
     * @param objects 要判断的对象数组
     *                * @return true：为空 false：非空
     */
    public static boolean isEmpty(Object[] objects) {
        return isNull(objects) || (objects.length == 0);
    }

    /**
     * * 判断一个对象数组是否非空
     *
     * @param objects 要判断的对象数组
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Object[] objects) {
        return !isEmpty(objects);
    }

    /**
     * * 判断一个Map是否为空
     *
     * @param map 要判断的Map
     * @return true：为空 false：非空
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return isNull(map) || map.isEmpty();
    }

    /**
     * * 判断一个Map是否为空
     *
     * @param map 要判断的Map
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    /**
     * * 判断一个字符串是否为空串
     *
     * @param str String
     * @return true：为空 false：非空
     */
    public static boolean isEmpty(String str) {
        return isNull(str) || "".equals(str.trim());
    }

    /**
     * * 判断一个字符串是否为非空串
     *
     * @param str String
     * @return true：非空串 false：空串
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * * 判断一个对象是否为空
     *
     * @param object Object
     * @return true：为空 false：非空
     */
    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     *
     * @param object Object
     * @return true：非空 false：空
     */
    public static boolean isNotNull(Object object) {
        return !isNull(object);
    }

    /**
     * 判断是否包含字符串
     * @param str 原本字符
     * @param ignoreCase 是否忽略大小写
     * @param parameters 判断是否存在的字符串数组、集合
     * @return
     */
    public static boolean isExistString(String str, boolean ignoreCase, String... parameters) {
        if (str != null && parameters != null) {
            for (String s : parameters) {
                if (ignoreCase) {
                    if (str.equalsIgnoreCase(trim(s))) {
                        return true;
                    }
                } else {
                    if (str.equals(trim(s))) {
                        return true;
                    }
                }

            }
        }
        return false;
    }

    /**
     * 去空格
     */
    public static String trim(String str) {
        return (str == null ? "" : str.trim());
    }
}
